#include "XgUpperMonitor.h"
#include <stdio.h>
#include "main.h"
#include "systemdata.h"
#include <stdlib.h>
#include "BatMonitor.h"
#include "bat_afe.h"
#include "drv_rtc.h"
#include "drv_usart1.h"
#include "tsdb_save_data.h"
#include "worktask.h"
#include "24Cxx.h"

static unsigned char upper_send_data[512];

static int auchCRCHi[256] = { // crc高位表
	0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
	0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
	0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
	0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
	0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
	0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
	0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
	0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
	0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
	0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40,
	0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
	0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
	0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
	0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40,
	0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
	0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
	0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
	0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
	0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
	0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
	0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
	0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40,
	0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
	0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
	0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
	0x80, 0x41, 0x00, 0xC1, 0x81, 0x40};

static int auchCRCLo[256] = { // crc低位表
	0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06,
	0x07, 0xC7, 0x05, 0xC5, 0xC4, 0x04, 0xCC, 0x0C, 0x0D, 0xCD,
	0x0F, 0xCF, 0xCE, 0x0E, 0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09,
	0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9, 0x1B, 0xDB, 0xDA, 0x1A,
	0x1E, 0xDE, 0xDF, 0x1F, 0xDD, 0x1D, 0x1C, 0xDC, 0x14, 0xD4,
	0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3,
	0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3,
	0xF2, 0x32, 0x36, 0xF6, 0xF7, 0x37, 0xF5, 0x35, 0x34, 0xF4,
	0x3C, 0xFC, 0xFD, 0x3D, 0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A,
	0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38, 0x28, 0xE8, 0xE9, 0x29,
	0xEB, 0x2B, 0x2A, 0xEA, 0xEE, 0x2E, 0x2F, 0xEF, 0x2D, 0xED,
	0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26,
	0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60,
	0x61, 0xA1, 0x63, 0xA3, 0xA2, 0x62, 0x66, 0xA6, 0xA7, 0x67,
	0xA5, 0x65, 0x64, 0xA4, 0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F,
	0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB, 0x69, 0xA9, 0xA8, 0x68,
	0x78, 0xB8, 0xB9, 0x79, 0xBB, 0x7B, 0x7A, 0xBA, 0xBE, 0x7E,
	0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5,
	0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71,
	0x70, 0xB0, 0x50, 0x90, 0x91, 0x51, 0x93, 0x53, 0x52, 0x92,
	0x96, 0x56, 0x57, 0x97, 0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C,
	0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E, 0x5A, 0x9A, 0x9B, 0x5B,
	0x99, 0x59, 0x58, 0x98, 0x88, 0x48, 0x49, 0x89, 0x4B, 0x8B,
	0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C,
	0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42,
	0x43, 0x83, 0x41, 0x81, 0x80, 0x40};

unsigned short XgBmsProtocolCrc(unsigned char *checkArray, unsigned int checkLen)
{
	// QByteArray chkData = checkArray;
	char *chkData = (char *)checkArray;

	unsigned short crcValue = 0xffff;
	unsigned char crcHi = 0xff; // 高位初始化
	unsigned char crcLo = 0xff; // 低位初始化
	for (int i = 0; i < checkLen; i++)
	{
		unsigned char crcIndex = crcHi ^ chkData[i]; // 查找crc表值
		crcHi = crcLo ^ (auchCRCHi[crcIndex] & 0xff);
		crcLo = auchCRCLo[crcIndex] & 0xff;
	}
	crcValue = (unsigned short)(crcHi << 8 | crcLo);

	return crcValue;
}

//static void xgSendRealTimeData(void)
//{ // 发送实时数据
//	SysConfData_t *confInfo = getSysConfData();
//	SysRunData_t *runInfo = getSysRunData();
//	memset(upper_send_data, 0, 512);
//	unsigned char index = 0;

//	upper_send_data[index++] = XG_MSG_HEADER_L;
//	upper_send_data[index++] = XG_MSG_HEADER_H;
//	upper_send_data[index++] = confInfo->fctData.devAddress;
//	upper_send_data[index++] = 0x02;
//	upper_send_data[index++] = 0x00;
//	upper_send_data[index++] = XG_CMD_CODE_READ;
//	upper_send_data[index++] = realDataGrpAddr;

//	upper_send_data[index++] = confInfo->fctData.batType;
//	

//	uint16_t remainCap = confInfo->fctData.realCap.value * runInfo->batSoc / 100;
//	upper_send_data[index++] = remainCap;
//	upper_send_data[index++] = (remainCap >> 8) & 0xff;
//	upper_send_data[index++] = confInfo->fctData.batNum;

//	upper_send_data[index++] = runInfo->batState; // 电池状态
//	upper_send_data[index++] = runInfo->packVol & 0xff;
//	upper_send_data[index++] = (runInfo->packVol >> 8) & 0xff;

//	upper_send_data[index++] = (runInfo->batCur) & 0xff;
//	upper_send_data[index++] = ((runInfo->batCur) >> 8) & 0xff;
//	upper_send_data[index++] = ((runInfo->batCur) >> 16) & 0xff;
//	upper_send_data[index++] = ((runInfo->batCur) >> 24) & 0xff;

//	upper_send_data[index++] = runInfo->batSoc; // SOC
//	upper_send_data[index++] = runInfo->batSoh; // SOH

//	if (confInfo->fctData.batNum > 24)
//	{
//		printf("batnum error,batNum max 24,batNum = %d\n", confInfo->fctData.batNum);
//		return;
//	}
//	unsigned char batNum = 0;
//	for (batNum = 0; batNum < 24; batNum++)
//	{
//		upper_send_data[index++] = runInfo->batVol[batNum] & 0xff;
//		upper_send_data[index++] = (runInfo->batVol[batNum] >> 8) & 0xff;
//		//		printf("%d.",runInfo->batVol[batNum]);
//	}
//	//	printf("\n");
//	
//	upper_send_data[index++] = runInfo->mosTemp; // MOS
//	upper_send_data[index++] = runInfo->envTemp; // 环境温度
//	upper_send_data[index++] = runInfo->tempOne; // TEMP1
//	upper_send_data[index++] = runInfo->tempTwo; // TEMP2

//	upper_send_data[index++] = runInfo->batMaxVol & 0xff; // 单体最高电压
//	upper_send_data[index++] = (runInfo->batMaxVol >> 8) & 0xff;
//	upper_send_data[index++] = runInfo->batMaxNum; // 编号

//	upper_send_data[index++] = (runInfo->batMinVol) & 0xff; // 单体最低电压
//	upper_send_data[index++] = (runInfo->batMinVol >> 8) & 0xff;
//	upper_send_data[index++] = runInfo->batMinNum; // 编号

//	upper_send_data[index++] = (runInfo->maxDiffVol) & 0xff; // 单体最大压差
//	upper_send_data[index++] = (runInfo->maxDiffVol >> 8) & 0xff;

//	upper_send_data[index++] = confInfo->fctData.cycleTimes.value & 0xff; // 循环次数
//	upper_send_data[index++] = (confInfo->fctData.cycleTimes.value >> 8) & 0xff;

//	upper_send_data[index++] = (runInfo->chgReqVol) & 0xff; // 充电需求电压
//	upper_send_data[index++] = (runInfo->chgReqVol >> 8) & 0xff;

//	upper_send_data[index++] = (runInfo->chgReqCur) & 0xff; // 充电需求电流
//	upper_send_data[index++] = (runInfo->chgReqCur >> 8) & 0xff;

//	upper_send_data[index++] = runInfo->balState & 0xff; // 电芯均衡状态
//	upper_send_data[index++] = (runInfo->balState >> 8) & 0xff;
//	upper_send_data[index++] = (runInfo->balState >> 16) & 0xff;
//	upper_send_data[index++] = (runInfo->balState >> 24) & 0xff;

//	upper_send_data[index++] = runInfo->sysSwState.stateByte & 0xff; // 开关状态，此处测试，全开
//	upper_send_data[index++] = (runInfo->sysSwState.stateByte >> 8) & 0xff;

//	upper_send_data[index++] = runInfo->volWarnByte.cellHgVolWarn & 0xff; // 故障代码
//	upper_send_data[index++] = (runInfo->volWarnByte.cellHgVolWarn >> 8) & 0xff;
//	upper_send_data[index++] = (runInfo->volWarnByte.cellHgVolWarn >> 16) & 0xff;
//	upper_send_data[index++] = (runInfo->volWarnByte.cellHgVolWarn >> 24) & 0xff;

//	upper_send_data[index++] = runInfo->volWarnByte.cellLowVolWarn & 0xff; // 故障代码
//	upper_send_data[index++] = (runInfo->volWarnByte.cellLowVolWarn >> 8) & 0xff;
//	upper_send_data[index++] = (runInfo->volWarnByte.cellLowVolWarn >> 16) & 0xff;
//	upper_send_data[index++] = (runInfo->volWarnByte.cellLowVolWarn >> 24) & 0xff;

//	upper_send_data[index++] = runInfo->volWarnByte.volWarn.byte & 0xff;

//	upper_send_data[index++] = runInfo->volProtByte.cellHgVolProt & 0xff;
//	upper_send_data[index++] = (runInfo->volProtByte.cellHgVolProt >> 8) & 0xff;
//	upper_send_data[index++] = (runInfo->volProtByte.cellHgVolProt >> 16) & 0xff;
//	upper_send_data[index++] = (runInfo->volProtByte.cellHgVolProt >> 24) & 0xff;

//	upper_send_data[index++] = runInfo->volProtByte.cellLowVolProt & 0xff;
//	upper_send_data[index++] = (runInfo->volProtByte.cellLowVolProt >> 8) & 0xff;
//	upper_send_data[index++] = (runInfo->volProtByte.cellLowVolProt >> 16) & 0xff;
//	upper_send_data[index++] = (runInfo->volProtByte.cellLowVolProt >> 24) & 0xff;

//	upper_send_data[index++] = runInfo->volProtByte.volProt.byte & 0xff;

//	upper_send_data[index++] = runInfo->tempWarnByte.byte & 0xff;
//	upper_send_data[index++] = runInfo->tempProtByte.byte & 0xff;

//	upper_send_data[index++] = runInfo->curProtByte.byte & 0xff;

//	upper_send_data[index++] = runInfo->afeProtByte.byte & 0xff;

//	getRtcTimeHex((char *)&upper_send_data[index]);
//	index += 6;

//	memcpy(&upper_send_data[index], SOFT_VERSION, 12);
//	index += 12;

//	upper_send_data[3] = (index - 5) & 0xff;
//	upper_send_data[4] = ((index - 5) >> 8) & 0xff;
//	unsigned short crcValue = XgBmsProtocolCrc(upper_send_data, index);
//	upper_send_data[index++] = crcValue & 0xff;
//	upper_send_data[index++] = (crcValue >> 8) & 0xff;

//	usart1_send(upper_send_data, index);
//	
////	for(int i=0;i<=index;i++)
////	{
//////		printf("i=[%d]",i);
////		printf("%02x ",upper_send_data[i]);
////	}
////	printf("\n");
//}

//// 读取参数
//static void xgSendSysConfData(void)
//{
//	SysConfData_t *confInfo = getSysConfData();
//	memset(upper_send_data, 0, 512);
//	unsigned short index = 0;

//	upper_send_data[index++] = XG_MSG_HEADER_L;
//	upper_send_data[index++] = XG_MSG_HEADER_H;
//	upper_send_data[index++] = confInfo->fctData.devAddress;
//	upper_send_data[index++] = 0x02;
//	upper_send_data[index++] = 0x00;
//	upper_send_data[index++] = XG_CMD_CODE_READ;
//	upper_send_data[index++] = sysParamGrpAddr;

//	upper_send_data[index++] = confInfo->fctData.batType;
//	upper_send_data[index++] = confInfo->fctData.batNum;
//	memcpy(&upper_send_data[index], confInfo->fctData.hdSerial, 12);
//	index += 12;
//	memcpy(&upper_send_data[index], confInfo->fctData.BtNum, 24);
//	index += 24;
//	upper_send_data[index++] = confInfo->fctData.normalCap.byte[0] & 0xff;
//	upper_send_data[index++] = confInfo->fctData.normalCap.byte[1] & 0xff;

//	upper_send_data[index++] = confInfo->fctData.realCap.byte[0] & 0xff;
//	upper_send_data[index++] = confInfo->fctData.realCap.byte[1] & 0xff;

//	upper_send_data[index++] = confInfo->fctData.cycleTimes.byte[0] & 0xff;
//	upper_send_data[index++] = confInfo->fctData.cycleTimes.byte[1] & 0xff;

//	upper_send_data[index++] = confInfo->fctData.preChargeTime.byte[0] & 0xff;
//	upper_send_data[index++] = confInfo->fctData.preChargeTime.byte[1] & 0xff;

//	upper_send_data[index++] = confInfo->fctData.poweroff_vol.byte[0] & 0xff;
//	upper_send_data[index++] = confInfo->fctData.poweroff_vol.byte[1] & 0xff;

//	upper_send_data[index++] = confInfo->fctData.wakeupCurrent.byte[0] & 0xff;
//	upper_send_data[index++] = confInfo->fctData.wakeupCurrent.byte[1] & 0xff;

//	upper_send_data[index++] = confInfo->fctData.key_check_enable & 0xff;

//	upper_send_data[index++] = confInfo->fctData.chgLimitMode & 0xff;
//	upper_send_data[index++] = confInfo->fctData.limitCurStopValue.byte[0] & 0xff;
//	upper_send_data[index++] = confInfo->fctData.limitCurStopValue.byte[1] & 0xff;

//	upper_send_data[index++] = confInfo->fctData.autoSleepEnable & 0xff;

//	upper_send_data[index++] = confInfo->fctData.Rsens.byte[0] & 0xff;
//	upper_send_data[index++] = confInfo->fctData.Rsens.byte[1] & 0xff;

//	upper_send_data[index++] = confInfo->fctData.devAddress & 0xff;

//	/////////////////////告警参数
//	upper_send_data[index++] = confInfo->warnData.batVolHigh.byte[0] & 0xff;
//	upper_send_data[index++] = confInfo->warnData.batVolHigh.byte[1] & 0xff;

//	upper_send_data[index++] = confInfo->warnData.batVolLow.byte[0] & 0xff;
//	upper_send_data[index++] = confInfo->warnData.batVolLow.byte[1] & 0xff;

//	upper_send_data[index++] = confInfo->warnData.batVolDiff.byte[0] & 0xff;
//	upper_send_data[index++] = confInfo->warnData.batVolDiff.byte[1] & 0xff;

//	upper_send_data[index++] = confInfo->warnData.packVolHigh.byte[0] & 0xff;
//	upper_send_data[index++] = confInfo->warnData.packVolHigh.byte[1] & 0xff;

//	upper_send_data[index++] = confInfo->warnData.packVolLow.byte[0] & 0xff;
//	upper_send_data[index++] = confInfo->warnData.packVolLow.byte[1] & 0xff;

//	upper_send_data[index++] = confInfo->warnData.mosTempHigh & 0xff;
//	upper_send_data[index++] = confInfo->warnData.envTempHigh & 0xff;
//	upper_send_data[index++] = confInfo->warnData.envTemplow & 0xff;
//	upper_send_data[index++] = confInfo->warnData.chgTempHigh & 0xff;
//	upper_send_data[index++] = confInfo->warnData.chgTempLow & 0xff;
//	upper_send_data[index++] = confInfo->warnData.dsgTempHigh & 0xff;
//	upper_send_data[index++] = confInfo->warnData.dsgTempLow & 0xff;

//	upper_send_data[index++] = confInfo->warnData.socLow & 0xff;
//	/////////////////////保护参数
//	upper_send_data[index++] = confInfo->errorData.batVolHigh.byte[0] & 0xff;
//	upper_send_data[index++] = confInfo->errorData.batVolHigh.byte[1] & 0xff;
//	upper_send_data[index++] = confInfo->errorData.batVolHighRecover.byte[0] & 0xff;
//	upper_send_data[index++] = confInfo->errorData.batVolHighRecover.byte[1] & 0xff;
//	upper_send_data[index++] = confInfo->errorData.batVolHighTime & 0xff;

//	upper_send_data[index++] = confInfo->errorData.batVolLow.byte[0] & 0xff;
//	upper_send_data[index++] = confInfo->errorData.batVolLow.byte[1] & 0xff;
//	upper_send_data[index++] = confInfo->errorData.batVolLowRecover.byte[0] & 0xff;
//	upper_send_data[index++] = confInfo->errorData.batVolLowRecover.byte[1] & 0xff;
//	upper_send_data[index++] = confInfo->errorData.batVolLowTime & 0xff;

//	upper_send_data[index++] = confInfo->errorData.sov_vol.byte[0] & 0xff;
//	upper_send_data[index++] = confInfo->errorData.sov_vol.byte[1] & 0xff;
//	upper_send_data[index++] = confInfo->errorData.suv_vol.byte[0] & 0xff;
//	upper_send_data[index++] = confInfo->errorData.suv_vol.byte[1] & 0xff;
//	upper_send_data[index++] = confInfo->errorData.sov_suv_dly_s & 0xff;

//	upper_send_data[index++] = confInfo->errorData.batVolDiff.byte[0] & 0xff;
//	upper_send_data[index++] = confInfo->errorData.batVolDiff.byte[1] & 0xff;
//	upper_send_data[index++] = confInfo->errorData.batVolDiffRecover.byte[0] & 0xff;
//	upper_send_data[index++] = confInfo->errorData.batVolDiffRecover.byte[1] & 0xff;
//	upper_send_data[index++] = confInfo->errorData.batVolDiffTime & 0xff;

//	upper_send_data[index++] = confInfo->errorData.packVolHigh.byte[0] & 0xff;
//	upper_send_data[index++] = confInfo->errorData.packVolHigh.byte[1] & 0xff;
//	upper_send_data[index++] = confInfo->errorData.packVolHighRecover.byte[0] & 0xff;
//	upper_send_data[index++] = confInfo->errorData.packVolHighRecover.byte[1] & 0xff;
//	upper_send_data[index++] = confInfo->errorData.packVolHighTime & 0xff;

//	upper_send_data[index++] = confInfo->errorData.packVolLow.byte[0] & 0xff;
//	upper_send_data[index++] = confInfo->errorData.packVolLow.byte[1] & 0xff;
//	upper_send_data[index++] = confInfo->errorData.packVolLowRecover.byte[0] & 0xff;
//	upper_send_data[index++] = confInfo->errorData.packVolLowRecover.byte[1] & 0xff;
//	upper_send_data[index++] = confInfo->errorData.packVolLowTime & 0xff;

//	upper_send_data[index++] = confInfo->errorData.mosTempHigh & 0xff;
//	upper_send_data[index++] = confInfo->errorData.mosTempHighRecover & 0xff;
//	upper_send_data[index++] = confInfo->errorData.mosTempHighTime & 0xff;

//	upper_send_data[index++] = confInfo->errorData.envTempHigh & 0xff;
//	upper_send_data[index++] = confInfo->errorData.envTempHighRecover & 0xff;
//	upper_send_data[index++] = confInfo->errorData.envTempHighTime & 0xff;

//	upper_send_data[index++] = confInfo->errorData.envTempLow & 0xff;
//	upper_send_data[index++] = confInfo->errorData.envTempLowRecover & 0xff;
//	upper_send_data[index++] = confInfo->errorData.envTempLowTime & 0xff;

//	upper_send_data[index++] = confInfo->errorData.chgTempHigh & 0xff;
//	upper_send_data[index++] = confInfo->errorData.chgTempHighRecover & 0xff;
//	upper_send_data[index++] = confInfo->errorData.chgTempHighTime & 0xff;

//	upper_send_data[index++] = confInfo->errorData.chgTempLow & 0xff;
//	upper_send_data[index++] = confInfo->errorData.chgTempLowRecover & 0xff;
//	upper_send_data[index++] = confInfo->errorData.chgTempLowTime & 0xff;

//	upper_send_data[index++] = confInfo->errorData.dsgTempHigh & 0xff;
//	upper_send_data[index++] = confInfo->errorData.dsgTempHighRecover & 0xff;
//	upper_send_data[index++] = confInfo->errorData.dsgTempHighTime & 0xff;

//	upper_send_data[index++] = confInfo->errorData.dsgTempLow & 0xff;
//	upper_send_data[index++] = confInfo->errorData.dsgTempLowRecover & 0xff;
//	upper_send_data[index++] = confInfo->errorData.dsgTempLowTime & 0xff;

//	upper_send_data[index++] = confInfo->errorData.batTempDiff & 0xff;
//	upper_send_data[index++] = confInfo->errorData.batTempDiffRecover & 0xff;
//	upper_send_data[index++] = confInfo->errorData.batTempDiffTime & 0xff;

//	upper_send_data[index++] = confInfo->errorData.chgOverCurrent.byte[0] & 0xff;
//	upper_send_data[index++] = confInfo->errorData.chgOverCurrent.byte[1] & 0xff;
//	upper_send_data[index++] = confInfo->errorData.chgOverCurRecoverTime.byte[0] & 0xff;
//	upper_send_data[index++] = confInfo->errorData.chgOverCurRecoverTime.byte[1] & 0xff;
//	upper_send_data[index++] = confInfo->errorData.chgOverCurrentTime & 0xff;

//	upper_send_data[index++] = confInfo->errorData.chgOverCurrent2.byte[0] & 0xff;
//	upper_send_data[index++] = confInfo->errorData.chgOverCurrent2.byte[1] & 0xff;
//	upper_send_data[index++] = confInfo->errorData.chgOverCur2RecoverTime.byte[0] & 0xff;
//	upper_send_data[index++] = confInfo->errorData.chgOverCur2RecoverTime.byte[1] & 0xff;
//	upper_send_data[index++] = confInfo->errorData.chgOverCurrent2Time & 0xff;

//	upper_send_data[index++] = confInfo->errorData.chgOverCurrent3.byte[0] & 0xff;
//	upper_send_data[index++] = confInfo->errorData.chgOverCurrent3.byte[1] & 0xff;
//	upper_send_data[index++] = confInfo->errorData.chgOverCur3RecoverTime.byte[0] & 0xff;
//	upper_send_data[index++] = confInfo->errorData.chgOverCur3RecoverTime.byte[1] & 0xff;
//	upper_send_data[index++] = confInfo->errorData.chgOverCurrent3Time & 0xff;

//	upper_send_data[index++] = confInfo->errorData.dsgOverCurrent.byte[0] & 0xff;
//	upper_send_data[index++] = confInfo->errorData.dsgOverCurrent.byte[1] & 0xff;
//	upper_send_data[index++] = confInfo->errorData.dsgOverCurRecoverTime.byte[0] & 0xff;
//	upper_send_data[index++] = confInfo->errorData.dsgOverCurRecoverTime.byte[1] & 0xff;
//	upper_send_data[index++] = confInfo->errorData.dsgOverCurrentTime & 0xff;

//	upper_send_data[index++] = confInfo->errorData.dsgOverCurrent2.byte[0] & 0xff;
//	upper_send_data[index++] = confInfo->errorData.dsgOverCurrent2.byte[1] & 0xff;
//	upper_send_data[index++] = confInfo->errorData.dsgOverCur2RecoverTime.byte[0] & 0xff;
//	upper_send_data[index++] = confInfo->errorData.dsgOverCur2RecoverTime.byte[1] & 0xff;
//	upper_send_data[index++] = confInfo->errorData.dsgOverCurrent2Time & 0xff;

//	upper_send_data[index++] = confInfo->errorData.dsgOverCurrent3.byte[0] & 0xff;
//	upper_send_data[index++] = confInfo->errorData.dsgOverCurrent3.byte[1] & 0xff;
//	upper_send_data[index++] = confInfo->errorData.dsgOverCur3RecoverTime.byte[0] & 0xff;
//	upper_send_data[index++] = confInfo->errorData.dsgOverCur3RecoverTime.byte[1] & 0xff;
//	upper_send_data[index++] = confInfo->errorData.dsgOverCurrent3Time & 0xff;

//	upper_send_data[index++] = confInfo->errorData.dsgOverCurrent4.byte[0] & 0xff;
//	upper_send_data[index++] = confInfo->errorData.dsgOverCurrent4.byte[1] & 0xff;
//	upper_send_data[index++] = confInfo->errorData.dsgOverCur4RecoverTime.byte[0] & 0xff;
//	upper_send_data[index++] = confInfo->errorData.dsgOverCur4RecoverTime.byte[1] & 0xff;
//	upper_send_data[index++] = confInfo->errorData.dsgOverCurrent4Time.byte[0] & 0xff;
//	upper_send_data[index++] = confInfo->errorData.dsgOverCurrent4Time.byte[1] & 0xff;

//	upper_send_data[index++] = confInfo->errorData.scdVol.byte[0] & 0xff;
//	upper_send_data[index++] = confInfo->errorData.scdVol.byte[1] & 0xff;

//	upper_send_data[index++] = confInfo->errorData.scdRecoverTime.byte[0] & 0xff;
//	upper_send_data[index++] = confInfo->errorData.scdRecoverTime.byte[1] & 0xff;

//	upper_send_data[index++] = confInfo->errorData.scdVolTime.byte[0] & 0xff;
//	upper_send_data[index++] = confInfo->errorData.scdVolTime.byte[1] & 0xff;

//	upper_send_data[index++] = confInfo->errorData.disOverCurLockTimes.byte[0] & 0xff;
//	upper_send_data[index++] = confInfo->errorData.disOverCurLockTimes.byte[1] & 0xff;

//	upper_send_data[index++] = confInfo->errorData.chgOverCurLockTimes.byte[0] & 0xff;
//	upper_send_data[index++] = confInfo->errorData.chgOverCurLockTimes.byte[1] & 0xff;

//	upper_send_data[index++] = confInfo->errorData.scdLockTimes.byte[0] & 0xff;
//	upper_send_data[index++] = confInfo->errorData.scdLockTimes.byte[1] & 0xff;

//	//////////////////均衡参数
//	upper_send_data[index++] = confInfo->balData.openVol.byte[0] & 0xff;
//	upper_send_data[index++] = confInfo->balData.openVol.byte[1] & 0xff;

//	upper_send_data[index++] = confInfo->balData.openDiffVol.byte[0] & 0xff;
//	upper_send_data[index++] = confInfo->balData.openDiffVol.byte[1] & 0xff;

//	upper_send_data[index++] = confInfo->balData.endDiffVol.byte[0] & 0xff;
//	upper_send_data[index++] = confInfo->balData.endDiffVol.byte[1] & 0xff;

//	upper_send_data[3] = (index - 5) & 0xff;
//	upper_send_data[4] = ((index - 5) >> 8) & 0xff;

//	unsigned short crcValue = XgBmsProtocolCrc(upper_send_data, index);
//	upper_send_data[index++] = crcValue & 0xff;
//	upper_send_data[index++] = (crcValue >> 8) & 0xff;

//	usart1_send(upper_send_data, index);
////		for(int i=0;i<=index;i++)
////	{
////		printf("%02x ",upper_send_data[i]);
////	}
////	printf("\n");
//}

//static void xgSendSysConfDataWriteRes(XgExcRes excRes)
//{ // 发送系统参数写入结果
//	SysConfData_t *confInfo = getSysConfData();
//	memset(upper_send_data, 0, 512);
//	unsigned char index = 0;

//	upper_send_data[index++] = XG_MSG_HEADER_L;
//	upper_send_data[index++] = XG_MSG_HEADER_H;
//	upper_send_data[index++] = confInfo->fctData.devAddress;
//	upper_send_data[index++] = 0x02;
//	upper_send_data[index++] = 0x00;
//	upper_send_data[index++] = XG_CMD_CODE_WRITE;
//	upper_send_data[index++] = sysParamGrpAddr;
//	upper_send_data[index++] = excRes & 0xff;

//	upper_send_data[3] = (index - 5) & 0xff;
//	upper_send_data[4] = ((index - 5) >> 8) & 0xff;
//	unsigned short crcValue = XgBmsProtocolCrc(upper_send_data, index);
//	upper_send_data[index++] = crcValue & 0xff;
//	upper_send_data[index++] = (crcValue >> 8) & 0xff;

//	usart1_send(upper_send_data, index);
////	printf("write\n");
////		for(int i=0;i<=index;i++)
////	{
////		printf("%02x ",upper_send_data[i]);
////	}
////	printf("\n");
//}

//static void xgSendSysCtrlExcRes(XgCtrlInfo ctrlInfo, XgExcRes excRes)
//{ // 发送控制命令执行结果
//	SysConfData_t *confInfo = getSysConfData();
//	memset(upper_send_data, 0, 512);
//	unsigned char index = 0;

//	upper_send_data[index++] = XG_MSG_HEADER_L;
//	upper_send_data[index++] = XG_MSG_HEADER_H;
//	upper_send_data[index++] = confInfo->fctData.devAddress;
//	upper_send_data[index++] = 0x02;
//	upper_send_data[index++] = 0x00;
//	upper_send_data[index++] = XG_CMD_CODE_WRITE;
//	upper_send_data[index++] = ctrlDataGrpAddr;

//	upper_send_data[index++] = ctrlInfo.ctrlObj;
//	upper_send_data[index++] = ctrlInfo.ctrlCode;
//	upper_send_data[index++] = excRes;

//	upper_send_data[3] = (index - 5) & 0xff;
//	upper_send_data[4] = ((index - 5) >> 8) & 0xff;
//	unsigned short crcValue = XgBmsProtocolCrc(upper_send_data, index);
//	upper_send_data[index++] = crcValue & 0xff;
//	upper_send_data[index++] = (crcValue >> 8) & 0xff;

//	usart1_send(upper_send_data, index);
////	printf("ctrl\n");
////		for(int i=0;i<=index;i++)
////	{
////		printf("%02x ",upper_send_data[i]);
////	}
////	printf("\n");
//}

//static void xgSendSysCaliExcRes(XgExcRes excRes)
//{
//	SysConfData_t *confInfo = getSysConfData();
//	memset(upper_send_data, 0, 512);
//	unsigned char index = 0;

//	upper_send_data[index++] = XG_MSG_HEADER_L;
//	upper_send_data[index++] = XG_MSG_HEADER_H;
//	upper_send_data[index++] = confInfo->fctData.devAddress;
//	upper_send_data[index++] = 0x02;
//	upper_send_data[index++] = 0x00;
//	upper_send_data[index++] = XG_CMD_CODE_WRITE;
//	upper_send_data[index++] = caliDataGrpAddr;

//	upper_send_data[index++] = excRes;

//	upper_send_data[3] = (index - 5) & 0xff;
//	upper_send_data[4] = ((index - 5) >> 8) & 0xff;
//	unsigned short crcValue = XgBmsProtocolCrc(upper_send_data, index);
//	upper_send_data[index++] = crcValue & 0xff;
//	upper_send_data[index++] = (crcValue >> 8) & 0xff;

//	usart1_send(upper_send_data, index);
////		for(int i=0;i<=index;i++)
////	{
////		printf("%02x ",upper_send_data[i]);
////	}
////	printf("\n");
//}

//static void xgSendErrRecordInfo(void)
//{
//	SysConfData_t *confInfo = getSysConfData();
//	XgErrRecord *errInfo = getSysErrRcdInfo();
//	memset(upper_send_data, 0, 512);
//	unsigned short index = 0;

//	upper_send_data[index++] = XG_MSG_HEADER_L;
//	upper_send_data[index++] = XG_MSG_HEADER_H;
//	upper_send_data[index++] = confInfo->fctData.devAddress;
//	upper_send_data[index++] = 0x02;
//	upper_send_data[index++] = 0x00;
//	upper_send_data[index++] = XG_CMD_CODE_READ;
//	upper_send_data[index++] = errRecordGrpAddr;

//	upper_send_data[index++] = errInfo->recordNum;
//	if (errInfo->recordNum > 30)
//	{
//		printf("error record num error,max 30,record num:%d\n", errInfo->recordNum);
//		return;
//	}

//	unsigned short i = 0;
//	for (i = 0; i < errInfo->recordNum; i++)
//	{
//		upper_send_data[index++] = errInfo->recordData[i].errorCode;
//		upper_send_data[index++] = errInfo->recordData[i].occurTimes & 0xff;
//		upper_send_data[index++] = (errInfo->recordData[i].occurTimes >> 8) & 0xff;
//		memcpy(&upper_send_data[index], errInfo->recordData[i].latestOccurTime, 6);
//		index += 6;
//	}
//	upper_send_data[3] = (index - 5) & 0xff;
//	upper_send_data[4] = ((index - 5) >> 8) & 0xff;
//	unsigned short crcValue = XgBmsProtocolCrc(upper_send_data, index);
//	upper_send_data[index++] = crcValue & 0xff;
//	upper_send_data[index++] = (crcValue >> 8) & 0xff;
//	usart1_send(upper_send_data, index);
//}

//static void xgSendErrRecordClrExcRes(XgExcRes excRes)
//{
//	SysConfData_t *confInfo = getSysConfData();
//	memset(upper_send_data, 0, 512);
//	unsigned char index = 0;

//	upper_send_data[index++] = XG_MSG_HEADER_L;
//	upper_send_data[index++] = XG_MSG_HEADER_H;
//	upper_send_data[index++] = confInfo->fctData.devAddress;
//	upper_send_data[index++] = 0x02;
//	upper_send_data[index++] = 0x00;
//	upper_send_data[index++] = XG_CMD_CODE_WRITE;
//	upper_send_data[index++] = errRecordGrpAddr;
//	upper_send_data[index++] = excRes;
//	upper_send_data[3] = (index - 5) & 0xff;
//	upper_send_data[4] = ((index - 5) >> 8) & 0xff;
//	unsigned short crcValue = XgBmsProtocolCrc(upper_send_data, index);
//	upper_send_data[index++] = crcValue & 0xff;
//	upper_send_data[index++] = (crcValue >> 8) & 0xff;

//	usart1_send(upper_send_data, index);
////		for(int i=0;i<=index;i++)
////	{
////		printf("%02x ",upper_send_data[i]);
////	}
////	printf("\n");
//}

//static void xgSendErrRecordLogClrExcRes(XgExcRes excRes)
//{
//	SysConfData_t *confInfo = getSysConfData();
//	memset(upper_send_data, 0, 512);
//	unsigned char index = 0;

//	upper_send_data[index++] = XG_MSG_HEADER_L;
//	upper_send_data[index++] = XG_MSG_HEADER_H;
//	upper_send_data[index++] = confInfo->fctData.devAddress;
//	upper_send_data[index++] = 0x02;
//	upper_send_data[index++] = 0x00;
//	upper_send_data[index++] = XG_CMD_CODE_WRITE;
//	upper_send_data[index++] = errRecordLogAddr;
//	upper_send_data[index++] = excRes;
//	upper_send_data[3] = (index - 5) & 0xff;
//	upper_send_data[4] = ((index - 5) >> 8) & 0xff;
//	unsigned short crcValue = XgBmsProtocolCrc(upper_send_data, index);
//	upper_send_data[index++] = crcValue & 0xff;
//	upper_send_data[index++] = (crcValue >> 8) & 0xff;

//	usart1_send(upper_send_data, index);
////		for(int i=0;i<=index;i++)
////	{
////		printf("%02x ",upper_send_data[i]);
////	}
////	printf("\n");
//}

//// 写入参数
//static void parseUpperConfData(unsigned char *data, unsigned char dataLen)
//{ // 解析上位机下发的系统配置参数
//	uint8_t index = 0;
//	SysConfData_t *confInfo = getSysConfData();
//	SysRunData_t *runinfo = getSysRunData();
//	/////////////////出厂参数
//	confInfo->fctData.batType = data[index++] & 0xff;
//	confInfo->fctData.batNum = data[index++] & 0xff;

//	memset(confInfo->fctData.hdSerial, 0, 12);
//	memcpy(confInfo->fctData.hdSerial, &data[index], 12);
//	index += 12;

//	memset(confInfo->fctData.BtNum, 0, 24);
//	memcpy(confInfo->fctData.BtNum, &data[index], 24);
//	index += 24;

//	confInfo->fctData.normalCap.byte[0] = data[index++] & 0xff;
//	confInfo->fctData.normalCap.byte[1] = data[index++] & 0xff;

//	confInfo->fctData.realCap.byte[0] = data[index++] & 0xff;
//	confInfo->fctData.realCap.byte[1] = data[index++] & 0xff;

//	runinfo->norCap_mAmS = ((uint64_t)confInfo->fctData.normalCap.value) * 360 * 1000 * 1000; // 实际容量初始化
//	runinfo->realCap_mAms = ((uint64_t)confInfo->fctData.realCap.value) * 360 * 1000 * 1000;  // 实际容量初始化
//	runinfo->batSoh = runinfo->realCap_mAms * 100 / runinfo->norCap_mAmS;

//	confInfo->fctData.cycleTimes.byte[0] = data[index++] & 0xff;
//	confInfo->fctData.cycleTimes.byte[1] = data[index++] & 0xff;

//	confInfo->fctData.preChargeTime.byte[0] = data[index++] & 0xff;
//	confInfo->fctData.preChargeTime.byte[1] = data[index++] & 0xff;

//	confInfo->fctData.poweroff_vol.byte[0] = data[index++] & 0xff;
//	confInfo->fctData.poweroff_vol.byte[1] = data[index++] & 0xff;

//	confInfo->fctData.wakeupCurrent.byte[0] = data[index++] & 0xff;
//	confInfo->fctData.wakeupCurrent.byte[1] = data[index++] & 0xff;

//	confInfo->fctData.key_check_enable = data[index++] & 0xff;
//	confInfo->fctData.chgLimitMode = data[index++] & 0xff;
//	confInfo->fctData.limitCurStopValue.byte[0] = data[index++] & 0xff;
//	confInfo->fctData.limitCurStopValue.byte[1] = data[index++] & 0xff;
//	confInfo->fctData.autoSleepEnable = data[index++] & 0xff;

//	confInfo->fctData.Rsens.byte[0] = data[index++] & 0xff;
//	confInfo->fctData.Rsens.byte[1] = data[index++] & 0xff;

//	confInfo->fctData.devAddress = data[index++] & 0xff;
//	////////////////告警参数
//	confInfo->warnData.batVolHigh.byte[0] = data[index++] & 0xff;
//	confInfo->warnData.batVolHigh.byte[1] = data[index++] & 0xff;

//	confInfo->warnData.batVolLow.byte[0] = data[index++] & 0xff;
//	confInfo->warnData.batVolLow.byte[1] = data[index++] & 0xff;

//	confInfo->warnData.batVolDiff.byte[0] = data[index++] & 0xff;
//	confInfo->warnData.batVolDiff.byte[1] = data[index++] & 0xff;

//	confInfo->warnData.packVolHigh.byte[0] = data[index++] & 0xff;
//	confInfo->warnData.packVolHigh.byte[1] = data[index++] & 0xff;

//	confInfo->warnData.packVolLow.byte[0] = data[index++] & 0xff;
//	confInfo->warnData.packVolLow.byte[1] = data[index++] & 0xff;

//	confInfo->warnData.mosTempHigh = data[index++] & 0xff;

//	confInfo->warnData.envTempHigh = data[index++] & 0xff;
//	confInfo->warnData.envTemplow = data[index++] & 0xff;

//	confInfo->warnData.chgTempHigh = data[index++] & 0xff;
//	confInfo->warnData.chgTempLow = data[index++] & 0xff;

//	confInfo->warnData.dsgTempHigh = data[index++] & 0xff;
//	confInfo->warnData.dsgTempLow = data[index++] & 0xff;

//	confInfo->warnData.socLow = data[index++] & 0xff;

//	/////////////////保护参数
//	confInfo->errorData.batVolHigh.byte[0] = data[index++] & 0xff;
//	confInfo->errorData.batVolHigh.byte[1] = data[index++] & 0xff;
//	confInfo->errorData.batVolHighRecover.byte[0] = data[index++] & 0xff;
//	confInfo->errorData.batVolHighRecover.byte[1] = data[index++] & 0xff;
//	confInfo->errorData.batVolHighTime = data[index++] & 0xff;

//	confInfo->errorData.batVolLow.byte[0] = data[index++] & 0xff;
//	confInfo->errorData.batVolLow.byte[1] = data[index++] & 0xff;
//	confInfo->errorData.batVolLowRecover.byte[0] = data[index++] & 0xff;
//	confInfo->errorData.batVolLowRecover.byte[1] = data[index++] & 0xff;
//	confInfo->errorData.batVolLowTime = data[index++] & 0xff;

//	confInfo->errorData.sov_vol.byte[0] = data[index++] & 0xff;
//	confInfo->errorData.sov_vol.byte[1] = data[index++] & 0xff;

//	confInfo->errorData.suv_vol.byte[0] = data[index++] & 0xff;
//	confInfo->errorData.suv_vol.byte[1] = data[index++] & 0xff;

//	confInfo->errorData.sov_suv_dly_s = data[index++] & 0xff;

//	confInfo->errorData.batVolDiff.byte[0] = data[index++] & 0xff;
//	confInfo->errorData.batVolDiff.byte[1] = data[index++] & 0xff;
//	confInfo->errorData.batVolDiffRecover.byte[0] = data[index++] & 0xff;
//	confInfo->errorData.batVolDiffRecover.byte[1] = data[index++] & 0xff;
//	confInfo->errorData.batVolDiffTime = data[index++] & 0xff;

//	confInfo->errorData.packVolHigh.byte[0] = data[index++] & 0xff;
//	confInfo->errorData.packVolHigh.byte[1] = data[index++] & 0xff;

//	confInfo->errorData.packVolHighRecover.byte[0] = data[index++] & 0xff;
//	confInfo->errorData.packVolHighRecover.byte[1] = data[index++] & 0xff;

//	confInfo->errorData.packVolHighTime = data[index++] & 0xff;

//	confInfo->errorData.packVolLow.byte[0] = data[index++] & 0xff;
//	confInfo->errorData.packVolLow.byte[1] = data[index++] & 0xff;

//	confInfo->errorData.packVolLowRecover.byte[0] = data[index++] & 0xff;
//	confInfo->errorData.packVolLowRecover.byte[1] = data[index++] & 0xff;

//	confInfo->errorData.packVolLowTime = data[index++] & 0xff;

//	confInfo->errorData.mosTempHigh = data[index++] & 0xff;
//	confInfo->errorData.mosTempHighRecover = data[index++] & 0xff;
//	confInfo->errorData.mosTempHighTime = data[index++] & 0xff;

//	confInfo->errorData.envTempHigh = data[index++] & 0xff;
//	confInfo->errorData.envTempHighRecover = data[index++] & 0xff;
//	confInfo->errorData.envTempHighTime = data[index++] & 0xff;

//	confInfo->errorData.envTempLow = data[index++] & 0xff;
//	confInfo->errorData.envTempLowRecover = data[index++] & 0xff;
//	confInfo->errorData.envTempLowTime = data[index++] & 0xff;

//	confInfo->errorData.chgTempHigh = data[index++] & 0xff;
//	confInfo->errorData.chgTempHighRecover = data[index++] & 0xff;
//	confInfo->errorData.chgTempHighTime = data[index++] & 0xff;

//	confInfo->errorData.chgTempLow = data[index++] & 0xff;
//	confInfo->errorData.chgTempLowRecover = data[index++] & 0xff;
//	confInfo->errorData.chgTempLowTime = data[index++] & 0xff;

//	confInfo->errorData.dsgTempHigh = data[index++] & 0xff;
//	confInfo->errorData.dsgTempHighRecover = data[index++] & 0xff;
//	confInfo->errorData.dsgTempHighTime = data[index++] & 0xff;

//	confInfo->errorData.dsgTempLow = data[index++] & 0xff;
//	confInfo->errorData.dsgTempLowRecover = data[index++] & 0xff;
//	confInfo->errorData.dsgTempLowTime = data[index++] & 0xff;

//	confInfo->errorData.batTempDiff = data[index++] & 0xff;
//	confInfo->errorData.batTempDiffRecover = data[index++] & 0xff;
//	confInfo->errorData.batTempDiffTime = data[index++] & 0xff;

//	confInfo->errorData.chgOverCurrent.byte[0] = data[index++] & 0xff;
//	confInfo->errorData.chgOverCurrent.byte[1] = data[index++] & 0xff;
//	confInfo->errorData.chgOverCurRecoverTime.byte[0] = data[index++] & 0xff;
//	confInfo->errorData.chgOverCurRecoverTime.byte[1] = data[index++] & 0xff;
//	confInfo->errorData.chgOverCurrentTime = data[index++] & 0xff;

//	confInfo->errorData.chgOverCurrent2.byte[0] = data[index++] & 0xff;
//	confInfo->errorData.chgOverCurrent2.byte[1] = data[index++] & 0xff;
//	confInfo->errorData.chgOverCur2RecoverTime.byte[0] = data[index++] & 0xff;
//	confInfo->errorData.chgOverCur2RecoverTime.byte[1] = data[index++] & 0xff;
//	confInfo->errorData.chgOverCurrent2Time = data[index++] & 0xff;

//	confInfo->errorData.chgOverCurrent3.byte[0] = data[index++] & 0xff;
//	confInfo->errorData.chgOverCurrent3.byte[1] = data[index++] & 0xff;
//	confInfo->errorData.chgOverCur3RecoverTime.byte[0] = data[index++] & 0xff;
//	confInfo->errorData.chgOverCur3RecoverTime.byte[1] = data[index++] & 0xff;
//	confInfo->errorData.chgOverCurrent3Time = data[index++] & 0xff;

//	confInfo->errorData.dsgOverCurrent.byte[0] = data[index++] & 0xff;
//	confInfo->errorData.dsgOverCurrent.byte[1] = data[index++] & 0xff;
//	confInfo->errorData.dsgOverCurRecoverTime.byte[0] = data[index++] & 0xff;
//	confInfo->errorData.dsgOverCurRecoverTime.byte[1] = data[index++] & 0xff;
//	confInfo->errorData.dsgOverCurrentTime = data[index++] & 0xff;

//	confInfo->errorData.dsgOverCurrent2.byte[0] = data[index++] & 0xff;
//	confInfo->errorData.dsgOverCurrent2.byte[1] = data[index++] & 0xff;
//	confInfo->errorData.dsgOverCur2RecoverTime.byte[0] = data[index++] & 0xff;
//	confInfo->errorData.dsgOverCur2RecoverTime.byte[1] = data[index++] & 0xff;
//	confInfo->errorData.dsgOverCurrent2Time = data[index++] & 0xff;

//	confInfo->errorData.dsgOverCurrent3.byte[0] = data[index++] & 0xff;
//	confInfo->errorData.dsgOverCurrent3.byte[1] = data[index++] & 0xff;
//	confInfo->errorData.dsgOverCur3RecoverTime.byte[0] = data[index++] & 0xff;
//	confInfo->errorData.dsgOverCur3RecoverTime.byte[1] = data[index++] & 0xff;
//	confInfo->errorData.dsgOverCurrent3Time = data[index++] & 0xff;

//	confInfo->errorData.dsgOverCurrent4.byte[0] = data[index++] & 0xff;
//	confInfo->errorData.dsgOverCurrent4.byte[1] = data[index++] & 0xff;
//	confInfo->errorData.dsgOverCur4RecoverTime.byte[0] = data[index++] & 0xff;
//	confInfo->errorData.dsgOverCur4RecoverTime.byte[1] = data[index++] & 0xff;
//	confInfo->errorData.dsgOverCurrent4Time.byte[0] = data[index++] & 0xff;
//	confInfo->errorData.dsgOverCurrent4Time.byte[1] = data[index++] & 0xff;

//	confInfo->errorData.scdVol.byte[0] = data[index++] & 0xff;
//	confInfo->errorData.scdVol.byte[1] = data[index++] & 0xff;

//	confInfo->errorData.scdRecoverTime.byte[0] = data[index++] & 0xff;
//	confInfo->errorData.scdRecoverTime.byte[1] = data[index++] & 0xff;
//	confInfo->errorData.scdVolTime.byte[0] = data[index++] & 0xff;
//	confInfo->errorData.scdVolTime.byte[1] = data[index++] & 0xff;

//	uint16_t afeDsgoverCurVol = confInfo->errorData.dsgOverCurrent4.value * confInfo->fctData.Rsens.value / 1000;
////	afe_set_SCD(confInfo->errorData.scdVol.value, confInfo->errorData.scdVolTime.value);				   // 设定短路及判定时间
////	afe_set_OCD(confInfo->errorData.dsgOverCurrent4.value, confInfo->errorData.dsgOverCurrent4Time.value); // 设定过流及判定时间
////	afe_set_OV_UV(confInfo->errorData.sov_vol.value, confInfo->errorData.suv_vol.value);				   // 设定单体欠压和过压
////	afe_set_OV_UV_Delay(confInfo->errorData.sov_suv_dly_s, confInfo->errorData.sov_suv_dly_s);

//	confInfo->errorData.disOverCurLockTimes.byte[0] = data[index++] & 0xff;
//	confInfo->errorData.disOverCurLockTimes.byte[1] = data[index++] & 0xff;

//	confInfo->errorData.chgOverCurLockTimes.byte[0] = data[index++] & 0xff;
//	confInfo->errorData.chgOverCurLockTimes.byte[1] = data[index++] & 0xff;

//	confInfo->errorData.scdLockTimes.byte[0] = data[index++] & 0xff;
//	confInfo->errorData.scdLockTimes.byte[1] = data[index++] & 0xff;

//	/////////////////均衡参数
//	confInfo->balData.openVol.byte[0] = data[index++] & 0xff;
//	confInfo->balData.openVol.byte[1] = data[index++] & 0xff;

//	confInfo->balData.openDiffVol.byte[0] = data[index++] & 0xff;
//	confInfo->balData.openDiffVol.byte[1] = data[index++] & 0xff;

//	confInfo->balData.endDiffVol.byte[0] = data[index++] & 0xff;
//	confInfo->balData.endDiffVol.byte[1] = data[index++] & 0xff;

//	saveSysConfData();
//}

//static void parseUpperCtrlData(XgCtrlInfo ctrlInfo)
//{
//	switch (ctrlInfo.ctrlObj)
//	{
//	case preChargeSwCtrl:
//	{ // 预充开关
//		// 在此添加预充开关的控制
//		afe_prechg_mos_ctrl(ctrlInfo.ctrlCode);
//		xgSendSysCtrlExcRes(ctrlInfo, xg_ExeSucc); // 回复执行结果
//	}
//	break;
//	case chargeSwCtrl:
//	{ // 充电开关
//		// 在此添加充电开关的控制
//		xgSendSysCtrlExcRes(ctrlInfo, xg_ExeSucc); // 回复执行结果
//		chgOptionEnable(ctrlInfo.ctrlCode);
//	}
//	break;
//	case dschargeSwCtrl:
//	{ // 放电开关
//		// 在此添加放电开关的控制
//		xgSendSysCtrlExcRes(ctrlInfo, xg_ExeSucc); // 回复执行结果
//		dsgOptionEnable(ctrlInfo.ctrlCode);
//	}
//	break;
//	case balanceSwCtrl:
//	{ // 均衡开关
//		// 在此添加均衡开关的控制
//		xgSendSysCtrlExcRes(ctrlInfo, xg_ExeSucc); // 回复执行结果
//		afe_balance_enable(ctrlInfo.ctrlCode);
//	}
//	break;
//		//		case heatSwCtrl:{				//加热开关
//		//			//在此添加加热开关的控制
//		//			afe_heat_mos_ctrl(ctrlInfo.ctrlCode);
//		//			xgSendSysCtrlExcRes(ctrlInfo,xg_ExeSucc);//回复执行结果
//		//		}break;
//	case otaUpdateCtrl:
//	{ // 程序升级开关
//		getSysRunData()->sysSwState.bits.SW_OTA = 1;
//		xgSendSysCtrlExcRes(ctrlInfo, xg_ExeSucc); // 回复执行结果
//	}
//	break;
//	case sysStateCtrl:
//	{ // 系统状态
//		// 在此添加系统状态的控制
//		switch (ctrlInfo.ctrlCode)
//		{
//		case 2:
//		{											   // 重启
//			xgSendSysCtrlExcRes(ctrlInfo, xg_ExeSucc); // 回复执行结果
//			afe_chg_mos_ctrl(false);
//			afe_dsg_mos_ctrl(false);
//			Soft_Reset();
//		}
//		break;
//		case 3:
//		{ // 休眠
//			if (sleep_enter_control() == 1)
//			{											   // 执行成功
//				xgSendSysCtrlExcRes(ctrlInfo, xg_ExeSucc); // 回复执行结果
//			}
//			else
//			{
//				xgSendSysCtrlExcRes(ctrlInfo, xg_ExeFailed); // 回复执行结果
//			}
//		}
//		break;
//		}
//	}
//	break;
//	}
//}

//static unsigned char parseUppercaliData(XgCaliInfo caliInfo)
//{
//	SysConfData_t *confInfo = getSysConfData();
//	SysRunData_t *runInfo = getSysRunData();
//	switch (caliInfo.caliObj)
//	{
//	case currentCali:
//	{ // 电流校准
//		float caliValue = ((float)(caliInfo.caliValue.stdCurrent)) / ((float)abs(runInfo->batRawCur));
//		if (caliValue >= 0.5 && caliValue <= 1.5)
//		{
//			confInfo->caliData.curRadio = (unsigned short)(caliValue * 10000.0);
//			return xg_ExeSucc;
//		}
//		else
//		{
//			return xg_ExeFailed;
//		}
//	}
//	break;
//	case bmsTimeCali:
//	{ // BMS时钟校准
//		char stdTimeStr[20] = {0};
//		memset(stdTimeStr, 0, 20);
//		memcpy(stdTimeStr, caliInfo.caliValue.stdTimeStr, 6);
//		set_hex_date_time(stdTimeStr);
//	}
//	break;
//	case batVolCali:
//	{ // 单体采样校准
//		unsigned short chkVol = 0;
//		unsigned short stdVol = 0;
//		unsigned char batNum = 0;
//		batNum = caliInfo.caliValue.stdBatValue.batNum;
//		stdVol = caliInfo.caliValue.stdBatValue.stdBatVol;
//		chkVol = runInfo->batVol[(batNum - 1) % 32];
//		unsigned int adcCaliValue = stdVol;
//		adcCaliValue = adcCaliValue * 10000 / chkVol;

//		if (adcCaliValue > 15000 || adcCaliValue < 5000)
//		{
//			return xg_ExeFailed;
//		}
//		if (batNum == 1)
//		{
//			confInfo->caliData.lowAdcRadio = confInfo->caliData.lowAdcRadio * adcCaliValue / 10000;
//		}
//		if (batNum == 17)
//		{
//			confInfo->caliData.highAdcRadio = confInfo->caliData.highAdcRadio * adcCaliValue / 10000;
//		}
//	}
//	break;
//	}
//	return xg_ExeSucc;
//}

//static unsigned char xgErrRecordClear()
//{ // 故障记录清除
//	sysErrRcdClear();
//	return xg_ExeSucc;
//}

//void timeCalibration(unsigned char *data)
//{
//	static bool timeCalibFlag = false;
//	if (!timeCalibFlag)
//	{
//		timeCalibFlag = true;
//		set_hex_date_time((char *)&data[1]);
//	}
//}

//static void sendEffectiveErrLog(void)
//{
//	SysConfData_t *confInfo = getSysConfData();
//	memset(upper_send_data, 0, 512);
//	unsigned char index = 0;
//	upper_send_data[index++] = XG_MSG_HEADER_L;
//	upper_send_data[index++] = XG_MSG_HEADER_H;
//	upper_send_data[index++] = confInfo->fctData.devAddress;
//	upper_send_data[index++] = 0x02;
//	upper_send_data[index++] = 0x00;
//	upper_send_data[index++] = XG_CMD_CODE_READ;
//	upper_send_data[index++] = errRecordLogAddr;
//	upper_send_data[index++] = xg_ExeSucc;

//	for (unsigned char i = 0; i < XG_STORE_HIST_DATA_LENGTH - 4; i++)
//	{
//		upper_send_data[index++] = getTsdbErrLog()->ErrLogData[i];
//	}

//	upper_send_data[3] = (index - 5) & 0xff;
//	upper_send_data[4] = ((index - 5) >> 8) & 0xff;

//	unsigned short crcValue = XgBmsProtocolCrc(upper_send_data, index);
//	upper_send_data[index++] = crcValue & 0xff;
//	upper_send_data[index++] = (crcValue >> 8) & 0xff;
//	usart1_send(upper_send_data, index);
//	
////	printf("send\n");
////		for(int i=8;i<index;i++)
////	{
////		printf("%x ",upper_send_data[i]);
////	}
////	printf("\n");
//}

//static void sendLastErrLogData(XgExcRes exres)
//{
//	SysConfData_t *confInfo = getSysConfData();
//	memset(upper_send_data, 0, 512);
//	unsigned char index = 0;
//	upper_send_data[index++] = XG_MSG_HEADER_L;
//	upper_send_data[index++] = XG_MSG_HEADER_H;
//	upper_send_data[index++] = confInfo->fctData.devAddress;
//	upper_send_data[index++] = 0x02;
//	upper_send_data[index++] = 0x00;
//	upper_send_data[index++] = XG_CMD_CODE_READ;
//	upper_send_data[index++] = errRecordLogAddr;

//	upper_send_data[index++] = exres;

//	upper_send_data[3] = (index - 5) & 0xff;
//	upper_send_data[4] = ((index - 5) >> 8) & 0xff;

//	unsigned short crcValue = XgBmsProtocolCrc(upper_send_data, index);
//	upper_send_data[index++] = crcValue & 0xff;
//	upper_send_data[index++] = (crcValue >> 8) & 0xff;
//	usart1_send(upper_send_data, index);
////		for(int i=0;i<=index;i++)
////	{
////		printf("%02x ",upper_send_data[i]);
////	}
////	printf("\n");
//}

//static void xgSendErrRecordLogData(unsigned char *data)
//{

//	unsigned char dataRecordLogRead = data[1];
//	switch (dataRecordLogRead)
//	{
//	case readFirstLog:
//	{ // 读取第一条
//		getTsdbErrLog()->totalNum = getErrlogNum();
//		getTsdbErrLog()->needReadRecordNum = 1;
//	}
//	break;
//	case readNextLog:
//	{ // 读取下一条
//		getTsdbErrLog()->needReadRecordNum++;
//	}
//	break;
//	}
//	if (getTsdbErrLog()->needReadRecordNum <= getTsdbErrLog()->totalNum)
//	{
//		read_record(getTsdbErrLog()->needReadRecordNum);
//		if (readTsdbErrLog())
//		{
//			sendEffectiveErrLog();
//			memset(getTsdbErrLog()->ErrLogData, 0, sizeof(XG_STORE_HIST_DATA_LENGTH));
//		}
//		else
//		{
//			sendLastErrLogData(xg_LastData);
//		}
//	}
//	else
//	{
//		sendLastErrLogData(xg_LastData);
//	}
//}

//static void parseUpperReadCmdData(unsigned char *data, unsigned short dataLen)
//{
//	unsigned char dataGrpAddr = data[0];
//	switch (dataGrpAddr)
//	{
//	case realDataGrpAddr:
//	{ // 实时数据地址,表示收到实时数据查询请求
//		timeCalibration(data);
//		xgSendRealTimeData();
//	}
//	break;
//	case sysParamGrpAddr:
//	{ // 系统参数地址，表示收到系统配置参数查询请求
//		xgSendSysConfData();
//	}
//	break;
//	case errRecordGrpAddr:
//	{ // 故障记录地址，表示收到故障记录信息查询请求
//		xgSendErrRecordInfo();
//	}
//	break;
//	case errRecordLogAddr:
//	{ // 故障记录数据日志，表示收到故障记录信息查询请求
//		xgSendErrRecordLogData(data);
//	}
//	break;
//	}
//}

//static void parseUpperWriteCmdData(unsigned char *data, unsigned short dataLen)
//{
//	unsigned char dataGrpAddr = data[0];
//	switch (dataGrpAddr)
//	{
//	case sysParamGrpAddr:
//	{										   // 系统参数地址,此处表示系统参数的写入
//		xgSendSysConfDataWriteRes(xg_ExeSucc); // 写入成功
//		parseUpperConfData(&data[1], dataLen - 1);
//	}
//	break;
//	case ctrlDataGrpAddr:
//	{ // 控制数据地址,此处表示控制数据的写入
//		XgCtrlInfo ctrlInfo;
//		ctrlInfo.ctrlObj = data[1];
//		ctrlInfo.ctrlCode = data[2];
//		parseUpperCtrlData(ctrlInfo);
//	}
//	break;
//	case caliDataGrpAddr:
//	{ // 校准数据地址,此处表示校准数据的写入
//		XgCaliInfo caliInfo;
//		caliInfo.caliObj = data[1];
//		memcpy(caliInfo.caliValue.value, &data[2], 16); // 拷贝16个字节的校准值
//		uint8_t excRes = parseUppercaliData(caliInfo);
//		xgSendSysCaliExcRes(excRes); // 回复执行结果
//		if (excRes == xg_ExeSucc)
//		{
//			saveSysConfData();
//		}
//		else
//		{
//			printf("cali error,not save!\n");
//		}
//	}
//	break;
//	case errRecordGrpAddr:
//	{										  // 故障记录数据地址,此处表示故障记录的清除
//		xgSendErrRecordClrExcRes(xg_ExeSucc); // 回复执行结果
//		xgErrRecordClear();
//	}
//	break;
//	case errRecordLogAddr:
//	{											 // 故障记录数据日志，此处表示故障记录的清除
//		xgSendErrRecordLogClrExcRes(xg_ExeSucc); // 回复执行结果
//		clear_record();							 // 清除故障记录
//	}
//	break;
//	}
//}

//static void parseUpperData(unsigned char *data, unsigned short dataLen)
//{
//	unsigned char cmdCode = data[5];
//	switch (cmdCode)
//	{
//	case XG_CMD_CODE_READ:
//	{
//		parseUpperReadCmdData(&data[6], dataLen - 6);
//	}
//	break;
//	case XG_CMD_CODE_WRITE:
//	{
//		parseUpperWriteCmdData(&data[6], dataLen - 6);
//	}
//	break;
//	}
//}


//// 鑫光锂电上位机协议解析，返回值：0、成功，1、失败
//void parse_xgld_protocol_data(uint8_t *data, uint16_t len)
//{
//	SysConfData_t *confInfo = getSysConfData();
////	printf("rev\n");
////	for (unsigned short i = 0; i < len; i++)
////	{
////		printf("%02x ", data[i]);
////	}
////	printf("\n");

//	if (len < 8)
//	{ // 长度不够
//		printf("length is too short\n");
//		return;
//	}
//	//	unsigned char headL = data[0];
//	//	unsigned char headH = data[1];
//	//	if (headL != XG_MSG_HEADER_L || headH != XG_MSG_HEADER_H) {//消息头不对
//	//		printf("message header is wrong\n");
//	//		return ;
//	//	}
//	int devAdr = data[2];
//	if (devAdr != 0xff && devAdr != confInfo->fctData.devAddress)
//	{
//		printf("Device address is wrong\n");
//		return;
//	}

//	int msgLen = data[4];
//	msgLen <<= 8;
//	msgLen |= data[3];
//	if (msgLen != len - 7)
//	{ // 长度不对
//		printf("length wrong\n");
//		return;
//	}
//	int crcValue = XgBmsProtocolCrc(data, len - 2);
//	char crcL = crcValue & 0xff;
//	char crcH = (crcValue >> 8) & 0xff;
//	if (crcL != data[len - 2] || crcH != data[len - 1])
//	{ // crc校验不通过
//		printf("crc check not pass\n");
//		return;
//	}
//	parseUpperData(&data[0], len);
//}
